﻿using System;
using System.Collections.Generic;
using System.Linq;
using Models;
using Interfaces;

namespace Controllers
{
    public class Controller
    {
        #region Fields

        private readonly DomæneCollection _collection;

        #endregion

        #region Creation

        public Controller()
        {
            _collection = new DomæneCollection();
        }

        #endregion

        #region Afdeling

        // hent den afdeling brugere ryger til, hvis deres afdeling bliver slettet
        public IAfdeling HentDefaultAfdeling()
        {
            return _collection.HentDefaultAfdeling();
        }

        // hent alle afdelinger
        public List<IAfdeling> HentAlleAfdelinger()
        {
            return _collection.AlleAfdelinger.Cast<IAfdeling>().ToList();
        }

        // tilføj ny afdeling til systemet
        // returner true hvis afdelingen blev tilføjet, ellers false
        public bool TilføjAfdeling(string navn)
        {
            return _collection.TilføjAfdeling(navn);
        }

        // rediger en eksisterende afdeling
        // returner true hvis afdelingen blev redigeret, ellers false 
        public bool RedigerAfdeling(IAfdeling iAfdeling, string navn)
        {
            var afdeling = (Afdeling) iAfdeling;
            return _collection.RedigerAfdeling(afdeling, navn);
        }

        // fjern en eksisterende afdeling
        // returner true hvis afdelingen blev fjernet, ellers false 
        public bool FjernAfdeling(IAfdeling afdeling)
        {
            var tmpAfdeling = (Afdeling) afdeling;
            return _collection.FjernAfdeling(tmpAfdeling);
        }

        #endregion

        #region Bruger

        // hent alle brugere
        public List<IBruger> HentAlleBrugere()
        {
            return _collection.HentAlleBrugere().Cast<IBruger>().ToList();
        }

        // hent bruger fra en given afdeling
        public List<IBruger> HentBrugereFraAfdeling(IAfdeling iAfdeling)
        {
            var afdeling = (Afdeling) iAfdeling;
            return afdeling.Brugere.Cast<IBruger>().ToList();
        }

        // hent brugere der ikke har lånt en given enhed
        public List<IBruger> HentBrugereDerIkkeHarLåntEnhed(IEnhed iEnhed)
        {
            var enhed = (Enhed) iEnhed;
            return _collection.HentBrugereDerIkkeHarLåntEnhed(enhed).Cast<IBruger>().ToList();
        }

        // hent brugere der ikke er fra en given afdeling
        public List<IBruger> HentBrugereIkkeFraAfdeling(IAfdeling iAfdeling)
        {
            var afdeling = (Afdeling) iAfdeling;
            return _collection.HentBrugereIkkeFraAfdeling(afdeling).Cast<IBruger>().ToList();
        }

        // hent brugeren der er tilknyttet et givent udlån
        public IBruger HentBrugerMedUdlån(IUdlån iUdlån)
        {
            var udlån = (Udlån) iUdlån;
            return udlån.Bruger;
        }

        // tilføj en ny bruger til systemet
        // returner true hvis brugeren blev tilføjet, ellers false 
        public bool TilføjBruger(IAfdeling iAfdeling, string initialer, string navn)
        {
            var afdeling = (Afdeling) iAfdeling;
            return _collection.TilføjBruger(afdeling, initialer, navn);
        }

        // rediger en eksisterende bruger
        // returner true hvis brugeren blev redigeret, ellers false 
        public bool RedigerBruger(IBruger iBruger, IAfdeling iAfdeling, string initialer, string navn)
        {
            var bruger = (Bruger) iBruger;
            var afdeling = (Afdeling) iAfdeling;
            return _collection.RedigerBruger(bruger, afdeling, initialer, navn);
        }

        // fjern en eksisterende bruger fra systemet
        // hvis brugeren blev fjernet returner true, ellers false
        public bool FjernBruger(IBruger iBruger)
        {
            var bruger = (Bruger) iBruger;
            return _collection.FjernBruger(bruger);
        }

        // hent en given brugers afdeling
        public IAfdeling HentBrugersAfdeling(IBruger iBruger)
        {
            var bruger = (Bruger) iBruger;
            return bruger.Afdeling;
        }

        // tjekker om der findes en bruger med de givne initialer
        // hvis der gør, returner true, ellers false
        public bool TjekInitialer(string initialer)
        {
            return _collection.BrugerEksisterer(initialer);
        }

        #endregion

        #region Alle Enheder

        // henter alle enheder af alle typer 
        public IEnumerable<IEnhed> HentAlleEnheder()
        {
            return _collection.AlleEnheder;
        }

        #endregion

        #region Diverse Enheder

        // henter alle diverse enheder
        public IEnumerable<IDiverse> HentAlleDiverseEnheder()
        {
            return _collection.AlleDiverseEnheder;
        }

        // hent specifikationer fra en given diverse enhed
        public List<ISpecifikation> HentSpecifikationerFraEnhed(IDiverse iDiverse)
        {
            var diverse = (Diverse) iDiverse;
            return _collection.HentSpecifikationerFraDiverseEnhed(diverse).Cast<ISpecifikation>().ToList();
        }

        // opretter en diverse enhed
        // hvis enhed blev oprettet returner true, ellers false
        public bool OpretDiverseEnhed(string navn, int totalAntal, DateTime oprettelsesDato)
        {
            return _collection.OpretDiverseEnhed(navn, totalAntal, oprettelsesDato);
        }

        // fjern en diverse enhed
        // hvis enhed blev fjernet returner true, ellers false
        public bool FjernDiverseEnhed(IDiverse iDiverse)
        {
            return _collection.FjernDiverseEnhed((Diverse)iDiverse);
        }

        // opdater en diverse enhed
        // hvis enhed blev opdateret returner true, ellers false
        public bool OpdaterDiverseEnhed(IDiverse iDiverse, string navn, int antal)
        {
            var diverse = (Diverse)iDiverse;
            return _collection.OpdaterDiverseEnhed(diverse, navn, antal);
        }

        // opretter en specifikation til en diverse enhed
        // hvis specifikationen blev oprettet returner true, ellers false
        public bool OpretSpecifikation(IDiverse iDiverse, string beskrivelse)
        {
            var diverse = (Diverse)iDiverse;
            return _collection.OpretSpecifikation(diverse, beskrivelse);
        }

        // fjerner en specifikation fra en diverse enhed
        // hvis specifikationen blev fjernet returner true, ellers false
        public bool FjernSpecifikation(ISpecifikation iSpecifikation)
        {
            var specifikation = (Specifikation) iSpecifikation;
            return _collection.FjernSpecifikation(specifikation);
        }

        #endregion
        
        #region Computer Enheder

        // henter alle computere
        public IEnumerable<IComputer> HentAlleComputere()
        {
            return _collection.AlleComputerEnheder;
        }

        // opretter en ny computer
        // hvis computeret blev oprettet returner true, ellers false
        public bool OpretComputerEnhed(string navn, int totalAntal, DateTime oprettelsesDato, string cpu, string hdd, string gpu, string ram, string bundkort, string skærm)
        {
            return _collection.OpretComputerEnhed(navn, totalAntal, oprettelsesDato, cpu, hdd, gpu, ram, bundkort, skærm);
        }

        // fjerner en eksisterende computer
        // hvis computeret blev oprettet returner true, ellers false
        public bool FjernComputerEnhed(IComputer iComputer)
        {
            var computer = (Computer) iComputer;
            return _collection.FjernComputerEnhed(computer);
        }

        // opdater en eksisterende computer
        // hvis computeret blev opdateret returner true, ellers false
        public bool OpdaterComputerEnhed(IComputer iComputer, string navn, string cpu, string hdd, string gpu, string ram, string bundkort, string skærm)
        {
            var computer = (Computer) iComputer;
            return _collection.OpdaterComputerEnhed(computer, navn, cpu, hdd, gpu, ram, bundkort, skærm);
        }

        #endregion

        #region Mobile Enheder

        // hent alle mobiler
        public IEnumerable<IMobil> HentAlleMobileEnheder()
        {
            return _collection.AlleMobileEnheder;
        }

        // tilføj en ny mobil enhed
        // hvis mobilen blev tilføjet returner true, ellers false
        public bool OpretMobilEnhed(string navn, int antal, DateTime oprettelsesDato, string mobilNummer, string imeiNummer)
        {
            return _collection.OpretMobilEnhed(navn, antal, oprettelsesDato, mobilNummer, imeiNummer);
        }

        // opdater en eksisterende mobil enhed
        // hvis mobilen blev opdateret returner true, ellers false
        public bool OpdaterMobilEnhed(IMobil iMobil, string navn, string mobilNummer, string imeiNummer)
        {
            var mobil = (Mobil) iMobil;
            return _collection.OpdaterMobilEnhed(mobil, navn, mobilNummer, imeiNummer);
        }

        // fjerner en eksisterende mobil enhed
        // hvis mobilen blev fjernet returner true, ellers false
        public bool FjernMobilEnhed(IMobil iMobil)
        {
            var mobil = (Mobil) iMobil;
            return _collection.FjernMobilEnhed(mobil);
        }

        // tjek om et givent mobilnummer findes i forvejen
        // hvis det gør, returner true, ellers false
        public bool TjekMobilNummer(string mobilNummer)
        {
            return _collection.MobilNummerEksisterer(mobilNummer);
        }

        // tjek om et givent IMEI nummer findes i forvejen
        // hvis det gør, returner true, ellers false
        public bool TjekImeiNummer(string imeiNummer)
        {
            return _collection.ImeiNummerEksisterer(imeiNummer);
        }
        #endregion

        #region Udlån

        // opret et nyt udlån i systemet
        // hvis det blev oprettet returner true, ellers false
        public bool OpretUdlån(IBruger iBruger, IEnhed iEnhed, int antal, DateTime dato)
        {
            var bruger = (Bruger)iBruger;
            var enhed = (Enhed)iEnhed;
            return _collection.OpretUdlån(bruger, enhed, antal, dato);
        }

        // udlån mobil til en bruger
        public bool UdlånMobil(IBruger iBruger, IEnhed iMobil, DateTime dato)
        {
            var bruger = (Bruger)iBruger;
            var enhed = (Enhed)iMobil;
            return _collection.OpretUdlån(bruger, enhed, 1, dato);
        }

        // udlån computer til en bruger
        public bool UdlånComputer(IBruger iBruger, IComputer iComputer, DateTime dato)
        {
            var bruger = (Bruger)iBruger; // cast IBruger til Bruger
            var enhed = (Enhed)iComputer; // cast IComputer til Enhed

            // kald generisk metode i collection
            return _collection.OpretUdlån(bruger, enhed, 1, dato);
        }

        // fjern et udlån fra systemet
        // hvis det blev fjernet returner true, ellers false
        public bool FjernUdlån(IUdlån iUdlån)
        {
            var udlån = (Udlån) iUdlån;
            return _collection.FjernUdlån(udlån);
        }

        // opdater et eksisterende udlån
        // hvis det blev opdateret returner true, ellers false
        public bool OpdaterUdlån(IUdlån selectedUdlån, int antal, DateTime dato)
        {
            return _collection.OpdaterUdlån((Udlån) selectedUdlån, antal, dato);
        }

        // hent alle udlån på den givne bruger
        public IEnumerable<IUdlån> HentUdlånMedBruger(IBruger iBruger)
        {
            var bruger = (Bruger) iBruger;
            return bruger.Udlån;
        }

        // hent alt historik på en bruger
        public IEnumerable<IHistorikUdlån> HentHistorikUdlånMedBruger(IBruger iBruger)
        {
            var bruger = (Bruger) iBruger;
            return bruger.HistorikUdlån;
        }

        // hent alle udlån der er lavet på en given enhed
        public IEnumerable<IUdlån> HentUdlånMedEnhed(IEnhed iEnhed)
        {
            var enhed = (Enhed) iEnhed;
            return enhed.Udlån;
        }

        // hent alt historik på en enhed
        public IEnumerable<IHistorikUdlån> HentHistorikUdlånMedEnhed(IEnhed iEnhed)
        {
            var enhed = (Enhed)iEnhed;
            return enhed.HistorikUdlån;
        }

        #endregion

        #region Software

        // henter alt software i systemet
        public IEnumerable<ISoftware> HentAltSoftware()
        {
            return _collection.AltSoftware;
        }

        // tilføj et nyt stykke software
        // hvis det blev tilføjet returner true, ellers false
        public bool TilføjSoftware(string navn, DateTime dato)
        {
            return _collection.TilføjSoftware(navn, dato);
        }

        // opdaterer et givent stykke software
        // hvis det blev opdateret returner true, ellers false
        public bool OpdaterSoftware(ISoftware software, string navn, DateTime dato)
        {
            return _collection.OpdaterSoftware((Software) software, navn, dato);
        }

        // fjerner et givent stykke software
        // hvis det blev fjernet returner true, ellers false
        public bool FjernSoftware(ISoftware selectedSoftware)
        {
            return _collection.FjernSoftware((Software)selectedSoftware);
        }

        // opretter en produktnøgle til et stykke software
        // hvis den blev oprettet returner true, ellers false
        public bool OpretProduktnøgle(ISoftware selectedSoftware, string nøgle, DateTime dato, int antal)
        {
            return _collection.TilføjProduktnøgle((Software) selectedSoftware, nøgle, dato, antal);
        }

        // opdaterer en given produktnøgle
        // hvis den blev opdateret returner true, ellers false
        public bool OpdaterProduktnøgle(IProduktnøgle produktNøgle, DateTime dato, int antal)
        {
            return _collection.OpdaterProduktnøgle((Produktnøgle)produktNøgle, dato, antal);
        }

        // fjerner en given produktnøgle
        // hvis den blev fjernet returner true, ellers false
        public bool FjernProduktnøgle(IProduktnøgle iProduktnøgle)
        {
            var produktNøgle = (Produktnøgle) iProduktnøgle;
            return _collection.FjernProduktnøgle(produktNøgle);
        }

        // henter alle computere der har lånt et givent stykke software
        public IEnumerable<IComputer> HentComputereMedSoftware(ISoftware iSoftware)
        {
            var software = (Software) iSoftware;
            return _collection.HentComputereMedSoftware(software).Cast<IComputer>();
        }

        // hent alle produktnøgler til et givent stykke software
        public IEnumerable<IProduktnøgle> HentProduktnøglerMedSoftware(ISoftware iSoftware)
        {
            var software = (Software) iSoftware;
            return software.ProduktNøgler;
        }

        // henter alle produktnøgler der stadig kan bruges til installationer, til et givent stykke software
        public IEnumerable<IProduktnøgle> HentLedigeProduktnøglerMedSoftware(ISoftware iSoftware)
        {
            var software = (Software) iSoftware;
            return _collection.HentLedigeProduktnøglerMedSoftware(software);
        }

        // hent alle computere der ikke har lånt et givent stykke software
        public IEnumerable<IComputer> HentComputereUdenSoftwareUdlån(ISoftware iSoftware)
        {
            var software = (Software) iSoftware;
            return _collection.HentComputereUdenSoftwareUdlån(software);
        }

        // hent alle computere med en given produktnøgle
        public IEnumerable<IComputer> HentComputereMedProduktnøgle(IProduktnøgle iNøgle)
        {
            var nøgle = (Produktnøgle) iNøgle;
            return _collection.HentComputereMedProduktnøgle(nøgle);
        }

        // hent alle softwareudlån til en given produktnøgle
        public IEnumerable<ISoftwareUdlån> HentUdlånMedProduktnøgle(IProduktnøgle iNøgle)
        {
            var nøgle = (Produktnøgle)iNøgle;
            return _collection.HentUdlånMedProduktnøgle(nøgle);
        }

        // tilføj et nyt software udlån
        // hvis det blev tilføjet returner true, ellers false
        public bool OpretSoftwareUdlån(IComputer computer, IProduktnøgle nøgle, DateTime dato)
        {
            return _collection.OpretSoftwareUdlån((Computer)computer, (Produktnøgle)nøgle, dato);
        }

        // fjern et eksisterende software udlån
        // hvis det blev fjernet returner true, ellers false
        public bool FjernSoftwareUdlån(IComputer computer, ISoftware selectedSoftware)
        {
            return _collection.FjernSoftwareUdlån((Computer)computer, (Software)selectedSoftware);
        }

        #endregion

        #region Rapport

        // udskriver alle en given brugers udlån til et word template
        public void UdskrivKontrakt(IBruger bruger)
        {
            var rapport = new Rapport();
            rapport.UdskrivKontrakt((Bruger) bruger);
        }

        // udskriver en liste af udlån til et word template
        public void UdskrivKontrakt(List<IUdlån> udlånsListe)
        {
            var rapport = new Rapport();
            rapport.UdskrivKontrakt(udlånsListe.Cast<Udlån>().ToList());
        }

        #endregion

    }
}